/////////////////////////////////////////////////////////////////////////////
// Name:        ax_messagebox.h
// Purpose:     An accessible message box implementation
// Author:      Julian Smart
// Modified by: 
// Created:     12/11/05 13:05:56
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"
#include "wx/valgen.h"

#include "ax/ax_messagebox.h"

#if defined(__WXMSW__)
#include "ax/bitmaps/exclamation_msw.xpm"
#include "ax/bitmaps/question_msw.xpm"
#include "ax/bitmaps/info_msw.xpm"
#elif defined(__WXGTK__)
#include "ax/bitmaps/exclamation_gtk.xpm"
#include "ax/bitmaps/question_gtk.xpm"
#include "ax/bitmaps/info_gtk.xpm"
#elif defined(__WXMAC__)
#include "ax/bitmaps/exclamation_generic.xpm"
#include "ax/bitmaps/question_generic.xpm"
#include "ax/bitmaps/info_generic.xpm"
#endif

/*
 * AxMessageDialog type definition
 */

IMPLEMENT_DYNAMIC_CLASS( AxMessageDialog, wxDialog )

/*
 * AxMessageDialog event table definition
 */

BEGIN_EVENT_TABLE( AxMessageDialog, wxDialog )

////@begin AxMessageDialog event table entries
    EVT_BUTTON( wxID_YES, AxMessageDialog::OnYesClick )

    EVT_BUTTON( wxID_YESTOALL, AxMessageDialog::OnYestoallClick )

    EVT_BUTTON( wxID_NO, AxMessageDialog::OnNoClick )

    EVT_BUTTON( wxID_NOTOALL, AxMessageDialog::OnNotoallClick )

    EVT_BUTTON( wxID_OK, AxMessageDialog::OnOkClick )

    EVT_BUTTON( wxID_CANCEL, AxMessageDialog::OnCancelClick )

////@end AxMessageDialog event table entries

END_EVENT_TABLE()

/*
 * AxMessageDialog constructors
 */

AxMessageDialog::AxMessageDialog( )
{
    m_messageDialogStyle = wxOK;
    m_displayNextTime = true;
    m_staticBitmap = NULL;
}

AxMessageDialog::AxMessageDialog( wxWindow* parent, const wxString& message, const wxString& caption, int style, const wxPoint& pos )
{
    m_messageDialogStyle = wxOK;
    m_displayNextTime = true;
    m_staticBitmap = NULL;

    Create(parent, message, caption, style, pos);
}

/*
 * wxMessageBoxEx creator
 */

bool AxMessageDialog::Create( wxWindow* parent, const wxString& message, const wxString& caption, int style, const wxPoint& pos )
{
    m_messageDialogStyle = style;
    m_message = message;

    SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
    wxDialog::Create( parent, wxID_ANY, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE );

    CreateControls();
    GetSizer()->Fit(this);
    GetSizer()->SetSizeHints(this);
    Centre();

    return true;
}

/*
 * Control creation for wxMessageBoxEx
 */

void AxMessageDialog::CreateControls()
{    
    AxMessageDialog* itemDialog1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemDialog1->SetSizer(itemBoxSizer2);

    wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5);

    wxBitmap m_staticBitmapBitmap;
    if (m_messageDialogStyle & wxICON_QUESTION)
        m_staticBitmapBitmap = itemDialog1->GetBitmapResource(wxT("question.xpm"));
    else if (m_messageDialogStyle & (wxICON_EXCLAMATION|wxICON_ERROR))
        m_staticBitmapBitmap = itemDialog1->GetBitmapResource(wxT("exclamation.xpm"));
    else
        m_staticBitmapBitmap = itemDialog1->GetBitmapResource(wxT("info.xpm"));

    m_staticBitmap = new wxStaticBitmap( itemDialog1, wxID_STATIC, m_staticBitmapBitmap, wxDefaultPosition, wxSize(32, 32), 0 );
    itemBoxSizer4->Add(m_staticBitmap, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    itemBoxSizer4->AddSpacer(10);

#if 1
    wxTextCtrl* textCtrl = new wxTextCtrl( itemDialog1, wxID_ANY, m_message, wxDefaultPosition, wxSize(300, 80), wxTE_READONLY|wxTE_MULTILINE );
    wxUnusedVar(textCtrl);
    itemBoxSizer4->Add(textCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
#else
    wxStaticText* itemStaticText6 = new wxStaticText( itemDialog1, wxID_STATIC, m_message, wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer4->Add(itemStaticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
#endif

    itemBoxSizer3->AddSpacer(5);

    wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer7, 0, wxALIGN_CENTER_HORIZONTAL, 5);

    if (m_messageDialogStyle & wxDISPLAY_NEXT_TIME)
    {
        wxCheckBox* displayNextTime = new wxCheckBox( itemDialog1, wxID_ANY, _("&Display next time"), wxDefaultPosition, wxDefaultSize, 0 );
        displayNextTime->SetHelpText(_("Check this to ask again next time."));
        displayNextTime->SetValidator(wxGenericValidator(& m_displayNextTime));
        itemBoxSizer7->Add(displayNextTime, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        itemBoxSizer7->AddStretchSpacer();
    }

    if (m_messageDialogStyle & wxYES)
    {
        wxButton* itemButton8 = new wxButton( itemDialog1, wxID_YES, _("&Yes"), wxDefaultPosition, wxDefaultSize, 0 );
        itemButton8->SetHelpText(_("Click this to answer yes."));
        itemBoxSizer7->Add(itemButton8, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    
    if (m_messageDialogStyle & wxYES_TO_ALL)
    {
        wxButton* itemButton9 = new wxButton( itemDialog1, wxID_YESTOALL, _("Yes to &All"), wxDefaultPosition, wxDefaultSize, 0 );
        itemButton9->SetHelpText(_("Click this to answer yes to all."));
        itemBoxSizer7->Add(itemButton9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    
    if (m_messageDialogStyle & wxNO)
    {
        wxButton* itemButton10 = new wxButton( itemDialog1, wxID_NO, _("&No"), wxDefaultPosition, wxDefaultSize, 0 );
        itemButton10->SetHelpText(_("Click this to answer no."));
        itemBoxSizer7->Add(itemButton10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    
    if (m_messageDialogStyle & wxNO_TO_ALL)
    {
        wxButton* itemButton11 = new wxButton( itemDialog1, wxID_NOTOALL, _("No &to All"), wxDefaultPosition, wxDefaultSize, 0 );
        itemButton11->SetHelpText(_("Click this to answer no to all."));
        itemBoxSizer7->Add(itemButton11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    
    if (m_messageDialogStyle & wxOK)
    {
        wxButton* itemButton12 = new wxButton( itemDialog1, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
        itemButton12->SetHelpText(_("Click this to answer OK, confirming the operation."));
        itemBoxSizer7->Add(itemButton12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    
    if (m_messageDialogStyle & wxCANCEL)
    {
        wxButton* itemButton13 = new wxButton( itemDialog1, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
        itemButton13->SetHelpText(_("Click this to cancel the operation."));
        itemBoxSizer7->Add(itemButton13, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    
    if (!m_yesLabel.IsEmpty())
        ((wxButton*) FindWindow(wxID_YES))->SetLabel(m_yesLabel);
    if (!m_noLabel.IsEmpty())
        ((wxButton*) FindWindow(wxID_NO))->SetLabel(m_noLabel);

    if (FindWindowById(wxID_OK, this))
        FindWindowById(wxID_OK, this)->SetFocus();
    else if (FindWindowById(wxID_YES, this))
         FindWindowById(wxID_YES, this)->SetFocus();
    else if (FindWindowById(wxID_NO, this))
         FindWindowById(wxID_NO, this)->SetFocus();
    else if (FindWindowById(wxID_YESTOALL, this))
         FindWindowById(wxID_YESTOALL, this)->SetFocus();
    else if (FindWindowById(wxID_NOTOALL, this))
         FindWindowById(wxID_NOTOALL, this)->SetFocus();
    else if (FindWindowById(wxID_CANCEL, this))
         FindWindowById(wxID_CANCEL)->SetFocus();

    m_adapter.Adapt(this);

    wxString text;
    if (m_messageDialogStyle & wxICON_QUESTION)
        text << _("Question. ");
    else if (m_messageDialogStyle & (wxICON_EXCLAMATION|wxICON_ERROR))
        text << _("Error. ");
    else
        text << _("Information. ");

    text << m_message << wxT("\n");

    wxArrayString buttons;    
    if (m_messageDialogStyle & wxYES)
        buttons.Add(_("Yes"));
    if (m_messageDialogStyle & wxNO)
        buttons.Add(_("No"));
    if (m_messageDialogStyle & wxYES_TO_ALL)
        buttons.Add(_("Yes to all"));
    if (m_messageDialogStyle & wxNO_TO_ALL)
        buttons.Add(_("No to all"));
    if (m_messageDialogStyle & wxOK)
        buttons.Add(_("OK"));
    if (m_messageDialogStyle & wxCANCEL)
        buttons.Add(_("Cancel"));

    if (buttons.GetCount() == 1)
    {
        text << wxString::Format(_("Press %s to continue."), buttons[0].c_str());
    }
    else
    {
        text << _("Press one of");
        size_t i;
        for (i = 0; i < buttons.GetCount(); i++)
        {
            if (i > 0)
                text << wxT(", ");
            else
                text << wxT(" ");
            text << buttons[i];
        }
    }

    m_adapter.FindAdapter(this)->Say(text, AxSpeechFlagsInviolate|AxSpeechFlagsPurge);
}

/*
 * Should we show tooltips?
 */

bool AxMessageDialog::ShowToolTips()
{
    return true;
}

/*
 * Get bitmap resources
 */

wxBitmap AxMessageDialog::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
    wxUnusedVar(name);
    if (name == _T("info.xpm"))
    {
        wxBitmap bitmap(info_xpm);
        return bitmap;
    }
    else if (name == _T("question.xpm"))
    {
        wxBitmap bitmap(question_xpm);
        return bitmap;
    }
    else if (name == _T("exclamation.xpm"))
    {
        wxBitmap bitmap(exclamation_xpm);
        return bitmap;
    }
    return wxNullBitmap;
}

/*
 * Get icon resources
 */

wxIcon AxMessageDialog::GetIconResource( const wxString& name )
{
    // Icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
}
/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_YES
 */

void AxMessageDialog::OnYesClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();
    EndModal(wxID_YES);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_YESTOALL
 */

void AxMessageDialog::OnYestoallClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();
    EndModal(wxID_YESTOALL);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_NO
 */

void AxMessageDialog::OnNoClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();
    EndModal(wxID_NO);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_NOTOALL
 */

void AxMessageDialog::OnNotoallClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();
    EndModal(wxID_NOTOALL);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
 */

void AxMessageDialog::OnOkClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();
    EndModal(wxID_OK);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
 */

void AxMessageDialog::OnCancelClick( wxCommandEvent& WXUNUSED(event) )
{
    EndModal(wxID_CANCEL);
}

// Convenience dialog
int AxMessageBox(const wxString& msg, const wxString& caption, int style, wxWindow* parent)
{
    AxMessageDialog dialog(parent, msg, caption, style);
    int id = dialog.ShowModal();
    if (id == wxID_YES)
        return wxYES;
    else if (id == wxID_NO)
        return wxNO;
    else if (id == wxID_YESTOALL)
        return wxYES_TO_ALL;
    else if (id == wxID_NOTOALL)
        return wxNO_TO_ALL;
    else if (id == wxID_OK)
        return wxOK;
    else if (id == wxID_CANCEL)
        return wxCANCEL;
    
    return wxCANCEL;
}
